package cn.jbolt.core.gen;

import cn.jbolt.core.annotation.TableBind;
import cn.jbolt.core.consts.JBoltConst;
import cn.jbolt.core.model.Permission;
import cn.jbolt.core.util.JBoltArrayUtil;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.DbKit;
import com.jfinal.plugin.activerecord.Model;

import java.util.ArrayList;
import java.util.List;

/**
 * 主逻辑生成器使用的对应关系Bean
 *
 * @ClassName: JBoltMainLogicBean
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2019年12月20日
 *
 */
public class JBoltMainLogicBean {
	/**
	 * 主要modelClass
	 */
	private Class<? extends Model<?>> mainModelClass;
	/**
	 * 子表配置生成
	 */
	private List<JBoltMainLogicBean> itemLogicBeans;
	/*
	 * index.html使用的UI布局 默认普通表格CRUD布局 normal_crud
	 * 可选normal_crud、normal_table、master_slave 对应普通crud类型、普通表格查询类型、主从表
	 */
	private IndexHtmlLayoutType indexHtmlLayoutType;
	/**
	 * 日志类型 如果需要save update delete等操作日志 就设置
	 */
	private SystemLogTargetType systemLogTargetType;
	/**
	 * 是否开启headBox
	 */
	private boolean needHeadBox;
	/**
	 * 是否开启footBox
	 */
	private boolean needFootBox;
	/**
	 * 是否开启leftBox
	 */
	private boolean needLeftBox;
	/**
	 * 是否开启rightBox
	 */
	private boolean needRightBox;
	/**
	 * controller service等java代码里 类注释 作者信息
	 */
	private String author;
	/**
	 * 项目根路径
	 */
	private String projectPath;
	/**
	 * 新模块对应的模块所在package
	 */
	private String javaPackage;
	/**
	 * 页面标题
	 */
	private String pageTitle;
	/**
	 * model的名字 例如model是user 名字就是用户
	 */
	private String dataName;
	/**
	 * 模块对应view层文件夹路径
	 */
	private String viewFolder;
	/**
	 * 后台查询是否开启分页
	 */
	private boolean needPaginate;
	/**
	 * 后台查询是否开启工具条 toolbar
	 */
	private boolean needToolbar;
	/**
	 * 后台管理是否开启排序
	 */
	private boolean needSort;
	/**
	 * 删除时是否做检测校验
	 */
	private boolean checkDelete;
	/**
	 * 是否有pid字段
	 */
	private boolean hasPid;
	/**
	 * 是否超管不校验
	 */
	private boolean unCheckIfSystemAdmin;
	/**
	 * 关键词匹配字段
	 */
	private String matchColumns;
	/**
	 * 排序字段
	 */
	private String orderColumn;
	/**
	 * 排序方式
	 */
	private String orderType;
	/**
	 * 路由controllerKey
	 */
	private String controllerKey;
	/**
	 * 数据源名称
	 */
	private String dataSource;
	/**
	 * 是否为主数据源
	 */
	private boolean isMainDataSource;
	/**
	 * 主键
	 */
	private String primaryKey;
	/**
	 * 启用用path注解 不启用默认需要配置route路由映射
	 */
	private boolean usePathAnnotation;
	/**
	 * 需要校验的权限集合 "PermissionKey.DEMO" 多个用 "PermissionKey.DEMO,PermissionKey.USER"
	 */
	private String checkPermissionKeys;
	/**
	 * 需要校验的权限 models
	 */
	private List<Permission> permissions;
	/**
	 * dialog的宽度和高度
	 */
	private String dialogArea;
	/**
	 * form表单分列数
	 */
	private int formColCount;
	/**
	 * form表单每列最少控件个数 formColCount>1时才有效
	 */
	private int formColControlMinCount;
	/**
	 * 需要一行后面的编辑按钮
	 */
	private boolean needTrEditBtn;
	/**
	 * 需要一行后面的删除按钮
	 */
	private boolean needTrDeleteBtn;

	/**
	 * 构造函数
	 *
	 * @param modelClass           model类
	 * @param projectPath          项目地址根路径
	 * @param javaPackage          生成controller service的package路径
	 * @param controllerKey        指向controller的路由映射key
	 * @param viewFolder           view层html存放目录
	 * @param pageTitle            生成index.html的网页标题
	 * @param dataName             数据名称 就是model的名字 例如model是user 名字就是用户
	 * @param needPaginate         是否需要分页
	 * @param needToolbar          index.html 是否需要工具条
	 * @param checkDelete          删除时是否做检测校验
	 * @param matchColumns         关键词查询匹配的字段 多个用逗号隔开
	 * @param orderColumn          默认排序字段 默认是主键ID
	 * @param orderType            默认排序方式 asc 或者 desc
	 * @param usePathAnnotation    是否使用@path注解 就不用去配置路由了
	 * @param unCheckIfSystemAdmin 是否启用权限超管员不校验 直接放行
	 * @param indexHtmlLayoutType  index.html 布局类型
	 */
	public JBoltMainLogicBean(Class<? extends Model<?>> modelClass, String projectPath, String javaPackage,
			String controllerKey, String viewFolder, String pageTitle, String dataName, boolean needPaginate,
			boolean needToolbar, boolean checkDelete, String matchColumns, String orderColumn, String orderType,
							  boolean usePathAnnotation, boolean unCheckIfSystemAdmin,
			IndexHtmlLayoutType indexHtmlLayoutType, String author) {
		if (!modelClass.isAnnotationPresent(TableBind.class)) {
			throw new RuntimeException("Model:" + modelClass.getName() + "必须有@TableBind注解");
		}
		TableBind tableBind = modelClass.getAnnotation(TableBind.class);
		this.dataSource = tableBind.dataSource();
		this.isMainDataSource = DbKit.MAIN_CONFIG_NAME.equals(tableBind.dataSource());
		this.primaryKey = tableBind.primaryKey();
		this.mainModelClass = modelClass;
		this.projectPath = projectPath;
		this.javaPackage = javaPackage;
		setControllerKey(controllerKey);
		setViewFolder(viewFolder);
		this.pageTitle = pageTitle;
		this.dataName = dataName;
		this.needPaginate = needPaginate;
		this.needToolbar = needToolbar;
		// 如果crud 有toolbar就默认不带tr编辑和删除 没有toolbar就默认带
		if (isCrudType()) {
			setNeedTrEditBtn(!needToolbar);
			setNeedTrDeleteBtn(!needToolbar);
		}

		this.checkDelete = checkDelete;
		this.matchColumns = matchColumns;
		setOrderColumn(orderColumn);
		setOrderType(orderType);
		this.usePathAnnotation = usePathAnnotation;
		this.unCheckIfSystemAdmin = unCheckIfSystemAdmin;

		this.dialogArea = "800,700";
		this.formColCount = 1;
		this.formColControlMinCount = 10;
		setIndexHtmlLayoutType(indexHtmlLayoutType);
		setAuthor(author);
	}

	public String getJavaPackage() {
		return javaPackage;
	}

	public void setJavaPackage(String javaPackage) {
		this.javaPackage = javaPackage;
	}

	public String getViewFolder() {
		return viewFolder;
	}

	public void setViewFolder(String viewFolder) {
		if (viewFolder.charAt(0) != JBoltConst.SLASH) {
			this.viewFolder = JBoltConst.SLASH_STR + viewFolder;
			return;
		}
		this.viewFolder = viewFolder;
	}

	public String getProjectPath() {
		return projectPath;
	}

	public void setProjectPath(String projectPath) {
		this.projectPath = projectPath;
	}

	public boolean getNeedPaginate() {
		return needPaginate;
	}

	public void setNeedPaginate(boolean needPaginate) {
		this.needPaginate = needPaginate;
	}

	public String getPageTitle() {
		return pageTitle;
	}

	public void setPageTitle(String pageTitle) {
		this.pageTitle = pageTitle;
	}

	public String getDataName() {
		return dataName;
	}

	public void setDataName(String dataName) {
		this.dataName = dataName;
	}

	public String getOrderColumn() {
		return orderColumn;
	}

	public void setOrderColumn(String orderColumn) {
		if (StrKit.isBlank(orderColumn)) {
			if (primaryKey.indexOf(",") != -1) {
				this.orderColumn = "id";
				return;
			}
			this.orderColumn = primaryKey;
			return;
		}
		this.orderColumn = orderColumn;
	}

	public String getOrderType() {
		return orderType;
	}

	public void setOrderType(String orderType) {
		if (StrKit.isBlank(orderType)) {
			this.orderType = "desc";
			return;
		}
		this.orderType = orderType;
	}

	public String getMatchColumns() {
		return matchColumns;
	}

	public void setMatchColumns(String matchColumns) {
		this.matchColumns = matchColumns;
	}

	public String getControllerKey() {
		return controllerKey;
	}

	public void setControllerKey(String controllerKey) {
		if (controllerKey.charAt(0) != JBoltConst.SLASH) {
			this.controllerKey = JBoltConst.SLASH_STR + controllerKey;
			return;
		}
		this.controllerKey = controllerKey;
	}

	public String getRealControllerKey() {
		if (StrKit.isBlank(controllerKey)) {
			return null;
		}
		if (controllerKey.charAt(0) == JBoltConst.SLASH) {
			return controllerKey.substring(1);
		}
		return controllerKey;
	}

	public boolean isNeedSort() {
		return needSort;
	}

	public boolean getNeedSort() {
		return needSort;
	}

	public void setNeedSort(boolean needSort) {
		this.needSort = needSort;
	}

	public boolean isHasPid() {
		return hasPid;
	}

	public boolean getHasPid() {
		return hasPid;
	}

	public void setHasPid(boolean hasPid) {
		this.hasPid = hasPid;
	}

	public boolean isUnCheckIfSystemAdmin() {
		return unCheckIfSystemAdmin;
	}

	public boolean getUnCheckIfSystemAdmin() {
		return unCheckIfSystemAdmin;
	}

	public void setUnCheckIfSystemAdmin(boolean unCheckIfSystemAdmin) {
		this.unCheckIfSystemAdmin = unCheckIfSystemAdmin;
	}

	public Class<? extends Model> getMainModelClass() {
		return mainModelClass;
	}

	public void setMainModelClass(Class<? extends Model<?>> mainModelClass) {
		this.mainModelClass = mainModelClass;
	}

	public List<JBoltMainLogicBean> getItemLogicBeans() {
		return itemLogicBeans;
	}

	public void setItemLogicBeans(List<JBoltMainLogicBean> itemLogicBeans) {
		this.itemLogicBeans = itemLogicBeans;
	}

	public String getPrimaryKey() {
		return primaryKey;
	}

	public String getPrimaryKeyAttr() {
		if (StrKit.isBlank(primaryKey) || primaryKey.indexOf(",") != -1) {
			return "id";
		}
		return StrKit.toCamelCase(primaryKey.toLowerCase());
	}

	public String getDataSource() {
		return dataSource;
	}

	public void setDataSource(String dataSource) {
		this.dataSource = dataSource;
	}

	public boolean getIsMainDataSource() {
		return isMainDataSource;
	}

	public void setIsMainDataSource(boolean mainDataSource) {
		isMainDataSource = mainDataSource;
	}

	public void setPrimaryKey(String primaryKey) {
		this.primaryKey = primaryKey;
	}

	public boolean isUsePathAnnotation() {
		return usePathAnnotation;
	}

	public void setUsePathAnnotation(boolean usePathAnnotation) {
		this.usePathAnnotation = usePathAnnotation;
	}

	public String getCheckPermissionKeys() {
		return checkPermissionKeys;
	}

	private void setCheckPermissionKeys(String checkPermissionKeys) {
		this.checkPermissionKeys = checkPermissionKeys;
	}

	public IndexHtmlLayoutType getIndexHtmlLayoutType() {
		return indexHtmlLayoutType;
	}

	public void setIndexHtmlLayoutType(IndexHtmlLayoutType indexHtmlLayoutType) {
		if (indexHtmlLayoutType == null) {
			this.indexHtmlLayoutType = IndexHtmlLayoutType.NORMAL_CRUD;
			return;
		}
		this.indexHtmlLayoutType = indexHtmlLayoutType;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		if (StrKit.isBlank(author)) {
			this.author = "JBolt-Generator";
			return;
		}
		this.author = author;
	}

	public boolean isNeedToolbar() {
		return needToolbar;
	}

	public boolean getNeedToolbar() {
		return needToolbar;
	}

	public void setNeedToolbar(boolean needToolbar) {
		this.needToolbar = needToolbar;
	}

	public boolean isNeedFootBox() {
		return needFootBox;
	}

	public boolean getNeedFootBox() {
		return needFootBox;
	}

	public void setNeedFootBox(boolean needFootBox) {
		this.needFootBox = needFootBox;
	}

	public boolean isNeedLeftBox() {
		return needLeftBox;
	}

	public boolean getNeedLeftBox() {
		return needLeftBox;
	}

	public void setNeedLeftBox(boolean needLeftBox) {
		this.needLeftBox = needLeftBox;
	}

	public boolean isNeedRightBox() {
		return needRightBox;
	}

	public boolean getNeedRightBox() {
		return needRightBox;
	}

	public void setNeedRightBox(boolean needRightBox) {
		this.needRightBox = needRightBox;
	}

	public boolean isNeedHeadBox() {
		return needHeadBox;
	}

	public boolean getNeedHeadBox() {
		return needHeadBox;
	}

	public void setNeedHeadBox(boolean needHeadBox) {
		this.needHeadBox = needHeadBox;
	}

	public boolean isNeedPaginate() {
		return needPaginate;
	}

	public boolean isCheckDelete() {
		return checkDelete;
	}

	public boolean isCrudType() {
		return indexHtmlLayoutType == IndexHtmlLayoutType.NORMAL_CRUD
				|| indexHtmlLayoutType == IndexHtmlLayoutType.MASTER_SLAVE_CRUD;
	}

	public boolean getIsCRUD() {
		return isCrudType();
	}

	public boolean getCheckDelete() {
		return checkDelete;
	}

	public void setCheckDelete(boolean checkDelete) {
		this.checkDelete = checkDelete;
	}

	public String getDialogArea() {
		return dialogArea;
	}

	public void setDialogArea(String dialogArea) {
		this.dialogArea = dialogArea;
	}

	public int getFormColCount() {
		return formColCount;
	}

	public void setFormColCount(int formColCount) {
		this.formColCount = formColCount;
	}

	public int getFormColControlMinCount() {
		return formColControlMinCount;
	}

	public void setFormColControlMinCount(int formColControlMinCount) {
		this.formColControlMinCount = formColControlMinCount;
	}

	public boolean isMasterSlave() {
		return indexHtmlLayoutType == IndexHtmlLayoutType.MASTER_SLAVE_CRUD
				|| indexHtmlLayoutType == IndexHtmlLayoutType.MASTER_SLAVE_TABLE;
	}

	public boolean getIsMasterSlave() {
		return isMasterSlave();
	}

	public boolean isNeedTrDeleteBtn() {
		return needTrDeleteBtn;
	}

	public boolean getNeedTrDeleteBtn() {
		return needTrDeleteBtn;
	}

	public void setNeedTrDeleteBtn(boolean needTrDeleteBtn) {
		this.needTrDeleteBtn = needTrDeleteBtn;
	}

	public boolean isNeedTrEditBtn() {
		return needTrEditBtn;
	}

	public boolean getNeedTrEditBtn() {
		return needTrEditBtn;
	}

	public void setNeedTrEditBtn(boolean needTrEditBtn) {
		this.needTrEditBtn = needTrEditBtn;
	}

	public SystemLogTargetType getSystemLogTargetType() {
		return systemLogTargetType;
	}
	public String getProjectSystemLogTargetType() {
		if(systemLogTargetType == null){
			return null;
		}
		return systemLogTargetType.getTargetTypeStr();
	}

	public void setSystemLogTargetType(SystemLogTargetType systemLogTargetType) {
		this.systemLogTargetType = systemLogTargetType;
	}

	public List<Permission> getPermissions() {
		return permissions;
	}

	public void setPermissions(List<Permission> permissions) {
		this.permissions = permissions;
		if(permissions == null || permissions.size() ==0){
			this.checkPermissionKeys = "PermissionKey.NONE";
		}else{
			String[] keys = JBoltArrayUtil.getStringArray(permissions,"permission_key");
			if(keys!=null && keys.length>0){
				if(keys.length == 1){
					this.checkPermissionKeys = "PermissionKey."+keys[0].toUpperCase();
				}else{
					List<String> ckeys = new ArrayList<>();
					for(String key:keys){
						ckeys.add("PermissionKey."+key.toUpperCase());
					}
					this.checkPermissionKeys = "{"+JBoltArrayUtil.join(ckeys,",")+"}";
				}
			}else{
				this.checkPermissionKeys = "PermissionKey.NONE";
			}
		}
	}
}
